package gqz.mvvm.view.custom;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

/**
 * Created by Administrator on 2018/3/5.
 * 三段式开关 By Gowcage
 * API 21 有颜色过渡动画
 */

public class MySwitch extends View {

    String TAG = "MySwitch-->";

    public static final int STATE_LEFT = 0;
    public static final int STATE_MIDDLE = 1;
    public static final int STATE_RIGHT = 2;
    private Paint mPaint, mTextPaint;
    private ValueAnimator valueAnim, colorAnim, textColorAnim;
    private OnCheckedChangeListener listener;

    private int mStatus = 0;
    private boolean NATIVE_MODE = false;//原生模式
    private int minDistance = 10;//最小移动距离

    private int mWidth = 75, mHeight = 25;//开关最小尺寸w:h = 3:1
    private int mHalfW, mHalfH;
    private float mRadius;//高度的1/2
    private int mPadding;//高度的1/10
    private float thumbRadius;//圆形按钮半径

    private int curPos;//thumb当前位置
    private float[] mArea = new float[4];//三段开关的区域,四个值
    private String[] texts = {"断开", "保持", "连接"};//开关三种状态的文本
    private String mThumbText = texts[0];
    //按钮位置
    private float thumbX = 0;

    //背景色
    private int bgColor = Color.rgb(0xcc, 0xcc, 0xcc);
    //按钮三种状态的颜色
    private int[] thumbColors = {Color.argb(0xff, 0xcc, 25, 25), Color.argb(0xff, 0xff, 0xff, 0xff), Color.argb(0xff, 0, 0xaa, 0x66)};
    private int mCurThumbColor = thumbColors[0];
    //按钮阴影颜色
    private int thumbShadowColor = Color.argb(0x99, 0, 0, 0), bgShadowColor = Color.argb(0x99, 0xcc, 0xcc, 0xcc);
    //三种状态的文字颜色
    private int[] mTextColors = {Color.argb(0xff, 0xdd, 0xdd, 0xdd), Color.argb(0xff, 0, 0, 0), Color.argb(0xff, 0xdd, 0xff, 0xdd)};
    private int mCurTextColor = mTextColors[0];

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    valueAnim = colorAnim = textColorAnim = null;
                    if (listener != null)
                        listener.onCheckedChange(MySwitch.this, mStatus);
                    break;
            }
            return false;
        }
    });

    public MySwitch(Context context) {
        super(context);
        init();
    }

    public MySwitch(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MySwitch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        Log.i(TAG, "init");
        setClickable(true);//解决onTouchEvent只接收down的问题
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        mPaint = new Paint();
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);
        mTextPaint = new Paint();
        mTextPaint.setDither(true);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.i(TAG, "onMeasure");
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mWidth = getMeasureSize(widthMeasureSpec, mWidth);
        mHeight = mWidth / 3;

        mHalfW = mWidth / 2;
        mHalfH = mHeight / 2;

        mRadius = mHeight / 2;
        mPadding = mHeight / 10;
        thumbRadius = mHalfH - mPadding;

        int arealong = mWidth - mHalfH * 2;
        int third = arealong / 3;
        int part = arealong / 20;
        mArea[0] = mHalfH;
        mArea[1] = mArea[0] + third - part;
        mArea[2] = mHalfH + third * 2 + part;
        mArea[3] = mWidth - mHalfH;

        switch (mStatus) {
            case 0:
                thumbX = mArea[0];
                break;
            case 1:
                if (NATIVE_MODE) break;
                thumbX = mHalfW;
                break;
            case 2:
                thumbX = mArea[3];
                break;
        }

        setMeasuredDimension(mWidth, mHeight);
    }

    private int getMeasureSize(int measureSpec, int defaultSize) {
        int result = 0;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        switch (mode) {
            case MeasureSpec.EXACTLY://定值或MATCH_PARENT
                result = size > defaultSize ? size : defaultSize;
                break;
            case MeasureSpec.AT_MOST://WARP_CONTENT
                result = defaultSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                result = size > defaultSize ? size : defaultSize;
                break;
        }

        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        Log.i(TAG, "onDraw");
        super.onDraw(canvas);
        drawBg(canvas);
        changeStyle(getAreaByPoint(thumbX, mHalfH));
        drawThumb(canvas, mCurThumbColor, thumbX, mHalfH);
        drawText(canvas, mThumbText, thumbX, mCurTextColor);

        /*//划范围线段
        canvas.drawLine(mArea[0], 0, mArea[0], mHeight, mTextPaint);
        canvas.drawLine(mArea[1], 0, mArea[1], mHeight, mTextPaint);
        canvas.drawLine(mArea[2], 0, mArea[2], mHeight, mTextPaint);
        canvas.drawLine(mArea[3], 0, mArea[3], mHeight, mTextPaint);*/

    }

    private void drawBg(Canvas canvas) {
        RectF rect = new RectF(0 + mPadding, 0 + mPadding, mWidth - mPadding, mHeight - mPadding);
        mPaint.setColor(bgColor);
        mPaint.setShadowLayer(mPadding / 2, 0, 0, bgShadowColor);
        canvas.drawRoundRect(rect, mRadius - mPadding, mRadius - mPadding, mPaint);
    }

    private void drawThumb(Canvas canvas, int thumbColor, float cx, float cy) {
        mPaint.setColor(thumbColor);
        mPaint.setShadowLayer(mPadding / 2, 0, 0, thumbShadowColor);
        canvas.drawCircle(cx, cy, mHalfH - mPadding, mPaint);
    }

    private void drawText(Canvas canvas, String text, float x, int color) {
        mTextPaint.setColor(color);
        mTextPaint.setTextSize(mHalfH / 4 * 3);
        mTextPaint.setStrokeWidth(1);
        Paint.FontMetricsInt fmi = mTextPaint.getFontMetricsInt();
        // 计算字体基线，实现垂直居中
        int baseline = (mHeight - fmi.bottom + fmi.top) / 2 - fmi.top;
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(text, x, baseline, mTextPaint);
    }

    //根据范围改变颜色
    private void changeStyle(int status) {
		if (status == -1) return;
        mThumbText = texts[status];
        if (isMove) {
            mCurThumbColor = thumbColors[status];
            mCurTextColor = mTextColors[status];
        }
        mStatus = status;
    }

    //按钮移动标识
    private boolean isMove = false;
    private float px = 0;
    private float _x, _y;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                _x = px = event.getX();
                _y = event.getY();
                if (getDistance(new PointF(thumbX, mHalfH), new PointF(_x, _y)) <= thumbRadius)
                    isMove = true;
                break;
            case MotionEvent.ACTION_MOVE:
                if (isMove) {
                    float x = thumbX + event.getX() - px;
                    float temp = x < mArea[0] ? mArea[0] : x > mArea[3] ? mArea[3] : x;
                    if (thumbX == temp) break;
                    thumbX = temp;
                    px = event.getX();
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                float upX = event.getX(), upY = event.getY();
                if (getDistance(new PointF(upX, upY), new PointF(_x, _y)) <= minDistance)
                    isMove = false;

                if (isMove) {
                    startValueAnimator(getAreaByPoint(thumbX, mHalfH));
                    isMove = false;
                } else {
                    startValueAnimator(getAreaByPoint(upX, upY));
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * ValueAnimator
     */
    private void startValueAnimator(int status) {
        if (status == -1) return;

        float targetPos = 0;
        int targetColor;
        int targetTextColor;

        targetColor = thumbColors[status];
        targetTextColor = mTextColors[status];
        switch (status) {
            case 0://断开
                targetPos = mArea[0];
                break;
            case 1://保持
                targetPos = mHalfW;
                break;
            case 2://连接
                targetPos = mArea[3];
                break;
            case -1:
                return;
        }
        if (thumbX == targetPos && !isMove) return;
        valueAnim = ValueAnimator.ofFloat(thumbX, targetPos);
        valueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                thumbX = (float) animation.getAnimatedValue();
                invalidate();
            }
        });

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            colorAnim = ValueAnimator.ofArgb(mCurThumbColor, targetColor);
            colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurThumbColor = (int) animation.getAnimatedValue();
                }
            });

            textColorAnim = ValueAnimator.ofArgb(mCurTextColor, targetTextColor);
            textColorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mCurTextColor = (int) animation.getAnimatedValue();
                }
            });
        }

        AnimatorSet set = new AnimatorSet();
        set.playTogether(valueAnim, colorAnim, textColorAnim);
        set.setDuration(400);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                handler.sendEmptyMessage(0);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        set.start();
    }

    /**
     * 计算两点之间的距离
     */
    private float getDistance(PointF p1, PointF p2) {
        float x = Math.abs(p1.x - p2.x);
        float y = Math.abs(p1.y - p2.y);
        float distance = (float) Math.sqrt(x * x + y * y);
        return distance;
    }

    /**
     * 判断触摸点在哪个范围中
     *
     * @return 0 1 2 ; 0=断开，1=保持，2=连接
     */
    private int getAreaByPoint(float x, float y) {
        if (NATIVE_MODE) {
            if (x < mHalfW && mHeight - mPadding > y && y > mPadding) return 0;
            if (x > mHalfW && mHeight - mPadding > y && y > mPadding) return 2;
        } else {
            if (x < mArea[1] && mHeight - mPadding > y && y > mPadding) return 0;
            if (x > mArea[2] && mHeight - mPadding > y && y > mPadding) return 2;
            if (x > mArea[1] && x < mArea[2] && mHeight - mPadding > y && y > mPadding) return 1;
        }
        return -1;
    }

    /**
     * 对外方法=================================================
     */

    public void setTrackColor(int color) {
        bgColor = color;
    }

    //设置按钮颜色
    public void setThumbColorL(int color) {
        thumbColors[0] = color;
    }

    public void setThumbColorM(int color) {
        thumbColors[1] = color;
    }

    public void setThumbColorR(int color) {
        thumbColors[2] = color;
    }

    //设置字体颜色
    public void setTextColorL(int color) {
        mTextColors[0] = color;
    }

    public void setTextColorM(int color) {
        mTextColors[1] = color;
    }

    public void setTextColorR(int color) {
        mTextColors[2] = color;
    }

    //设置文本内容
    public void setTextL(String text) {
        texts[0] = text;
    }

    public void setTextM(String text) {
        texts[1] = text;
    }

    public void setTextR(String text) {
        texts[2] = text;
    }

    //设置选中状态，传0 1 2
    public void setChecked(int status) {
        if ((status > 2 && status < 0) || mStatus == status) return;
        if (status == 1 && NATIVE_MODE) return;
        startValueAnimator(status);
        mStatus = status;
    }

    //设置是否原生模式，即只有两种选择状态
    public void setPrimaryMode(boolean onoff) {
        this.NATIVE_MODE = onoff;
    }

    /**
     * 接口
     */
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        this.listener = listener;
    }

    public interface OnCheckedChangeListener {
        void onCheckedChange(View view, int status);//return 0 1 2 , 0=left,1=middle,2=right
    }
}
